import * as cloudDb from '@agconnect/database-server';
import { collect } from './model/collect';
import { resource } from './model/resource';
import { ResourceResp } from './model/ResourceResp';
import * as agc from '@agconnect/common-server';
import * as Utils from './utils/Utils.js';
import { topic } from './model/topic';
import { user_topic } from './model/user_topic';
import { user_like } from './model/user_like';
import { user_history } from './model/user_history';
import { topic_resource } from './model/topic_resource';

const ZONE_NAME = "HarmonyOSDeveloper";

export class DatabaseHelper {
  logger;
  cloudDbZone;

  constructor(context, logger) {
    this.logger = logger;
    const credential = Utils.getCredential(context, logger);
    try {
      // 初始化AGCClient
      logger.info("begin to init agcClient");
      let agcClient;
      try {
        agcClient = agc.AGCClient.getInstance();
      } catch {
        agc.AGCClient.initialize(credential);
        agcClient = agc.AGCClient.getInstance();
      }
      // 初始化AGConnectCloudDB实例
      logger.info("begin to init cloudDb");
      let cloudDbInstance;
      try {
        cloudDbInstance = cloudDb.AGConnectCloudDB.getInstance(agcClient);
      } catch {
        cloudDb.AGConnectCloudDB.initialize(agcClient);
        cloudDbInstance = cloudDb.AGConnectCloudDB.getInstance(agcClient);
      }
      // 创建CloudDBZoneConfig配置对象，并设置云侧CloudDB zone名称，打开Cloud DB zone实例
      const cloudDBZoneConfig = new cloudDb.CloudDBZoneConfig(ZONE_NAME);
      this.cloudDbZone = cloudDbInstance.openCloudDBZone(cloudDBZoneConfig);
    } catch (err) {
      logger.error("init CloudDBZoneWrapper error: " + err);
    }
  }

  async queryResource(userid) {
    let resList = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      let likedIds = [];
      let collectedIds = [];
      let historyIds = [];

      const collectQuery = cloudDb.CloudDBZoneQuery.where(collect).orderByDesc("collect_time");
      collectQuery.equalTo('user_id', userid)
      const collectResp = await this.cloudDbZone.executeQuery(collectQuery);
      let collectData = collectResp.getSnapshotObjects();
      this.logger.info("collectQuery success ");
      console.log('collectData=>', collectData);

      if (collectData.length <= 0) {
        return [];
      }

      let rids = []
      for (let i = 0; i < collectData.length; i++) {
        let resId: string = collectData[i].getResource_id();
        if (resId && resId.trim().length > 0) {
          rids.push(resId)
        }
      }
      likedIds = await this.queryLikedIds(userid);
      collectedIds = await this.queryCollectedIds(userid);
      // historyIds = await this.queryHistoryIds(userid);
      this.logger.info("collectedIds collectedIds:" + collectedIds);
      this.logger.info("queryResource rids:" + rids);
      const resQuery = cloudDb.CloudDBZoneQuery.where(resource);
      resQuery.in('id', rids)
      const resResp = await this.cloudDbZone.executeQuery(resQuery);
      let resData = resResp.getSnapshotObjects();
      this.logger.info("queryResource success");
      this.logger.info('resData=>', resData);
      if (resData.length > 0) {
        resData.sort(function (a, b) {
          return rids.indexOf(a.getId()) - rids.indexOf(b.getId()); //	降序，升序则反之
        });
        let topics: topic[] = await this.queryTopic();
        for (let i = 0; i < resData.length; i++) {
          let dataQ: resource = resData[i];
          resList.push(new ResourceResp(
            dataQ.getId(),
            dataQ.getTitle(),
            dataQ.getBrief(),
            dataQ.getHeader_src(),
            dataQ.getType(),
            dataQ.getWeb_url(),
            dataQ.getPublish_date(),
            this.getTopicNames(topics, dataQ.getTopics()),
            dataQ.getViews_count(),
            dataQ.getCollect_count(),
            dataQ.getLikes_count(),
            dataQ.getTag(),
            dataQ.getBanner_src(),
            dataQ.getMedia_src(),
            likedIds.indexOf(dataQ.getId()) !== -1, // isLiked
            collectedIds.indexOf(dataQ.getId()) !== -1, // isCollected
            // historyIds.indexOf(dataQ.getId()) !== -1 // isViewed
            null // isViewed
          ))
        }
      }
    } catch (error) {
      this.logger.info("query resource error " + error);
    } finally {
      return resList;
    }
  }

  async queryLikedIds(userid) {
    let likedIds = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const likeQuery = cloudDb.CloudDBZoneQuery.where(user_like);
      likeQuery.equalTo('user_id', userid);
      const likeResp = await this.cloudDbZone.executeQuery(likeQuery);
      let likeData = likeResp.getSnapshotObjects();
      this.logger.info("query like resource success ");
      console.log('resp like likeData=>', likeData.length);
      for (let index = 0; index < likeData.length; index++) {
        const element: user_like = likeData[index];
        likedIds.push(element.getResource_id());
      }
      return likedIds;
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryCollectedIds(userid) {
    let collectedIds = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const collectedQuery = cloudDb.CloudDBZoneQuery.where(collect);
      collectedQuery.equalTo('user_id', userid);
      const collectedResp = await this.cloudDbZone.executeQuery(collectedQuery);
      let collectedData = collectedResp.getSnapshotObjects();
      this.logger.info("query collected resource success ");
      console.log('resp collected=>', collectedResp.length);
      for (let index = 0; index < collectedData.length; index++) {
        const element: collect = collectedData[index];
        collectedIds.push(element.getResource_id());
      }
      return collectedIds;
    } catch (error) {
      this.logger.info("queryCollectedIds error " + error);
    }
  }

  async queryHistoryIds(userid) {
    let historyIds = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const historyQuery = cloudDb.CloudDBZoneQuery.where(user_history);
      historyQuery.equalTo('user_id', userid);
      const historyResp = await this.cloudDbZone.executeQuery(historyQuery);
      let historyData = historyResp.getSnapshotObjects();
      this.logger.info("query historyData resource success ");
      console.log('resp historyData=>', historyData.length);
      for (let index = 0; index < historyData.length; index++) {
        const element: user_history = historyData[index];
        historyIds.push(element.getResource_id());
      }
      return historyIds;
    } catch (error) {
      this.logger.info("queryHistoryIds error " + error);
    }
  }

  async queryTopic() {
    // 查询所有主题
    const cloudDBZoneQuery = cloudDb.CloudDBZoneQuery.where(topic);
    const resp = await this.cloudDbZone.executeQuery(cloudDBZoneQuery);
    let listData = resp.getSnapshotObjects();
    this.logger.info("query topic success ");
    console.log('queryTopic listData=>', listData.length);
    return listData;
  }

  getTopicNames(topics: topic[], tidStr: string) {
    let topicNames = []
    let topicIds: string[] = tidStr.split(',');
    for (let index = 0; index < topicIds.length; index++) {
      const tid = topicIds[index];
      let tp: topic[] = topics.filter(tp => tp.getId() === tid);
      topicNames.push(tp[0].getName())
    }
    return topicNames;
  }
}